﻿using System;
using System.Threading.Tasks;
using Wombat.Core;
using Wombat.Core.Gates;
using Wombat.Core.Services;
using Wombat.WcfClientGate;
using Wombat.WcfGate;

namespace Wombat.Bootstrappers.Essentials
{
    public partial class Bootstrap: IBootstrapper, IDisposable
    {
        private readonly IConfigurationServiceLoader _configurationServiceLoader;
        private readonly IDataService _dataService;
        private readonly FloatStorageGate.Factory _floatStorageGateFactory;
        private readonly WcfServiceGateHost.Factory _serviceEndpointGateFactory;
        private readonly CodeBlockExecuterGate.Factory _codeBlockExecuterGateFactory;
        private readonly IObservationManager _observationManager;
        private readonly ITagRepositoryLoader _tagRepositoryLoader;
        private readonly WcfExportGate.Factory _wcfExportGateFactory;

        public Bootstrap(IConfigurationServiceLoader configurationServiceLoader, IDataService dataService,
            FloatStorageGate.Factory floatStorageGateFactory, WcfServiceGateHost.Factory serviceEndpointGateFactory,
            CodeBlockExecuterGate.Factory codeBlockExecuterGateFactory, WcfExportGate.Factory wcfExportGateFactory,
            IObservationManager observationManager, ITagRepositoryLoader tagRepositoryLoader)
        {
            _configurationServiceLoader = configurationServiceLoader;
            _dataService = dataService;
            _floatStorageGateFactory = floatStorageGateFactory;
            _serviceEndpointGateFactory = serviceEndpointGateFactory;
            _codeBlockExecuterGateFactory = codeBlockExecuterGateFactory;
            _observationManager = observationManager;
            _tagRepositoryLoader = tagRepositoryLoader;
            _wcfExportGateFactory = wcfExportGateFactory;
        }

        public async Task BootstrapAsync()
        {
            await LoadConfiguration();
            ((IInitializable)_dataService).Initialize();
            await LoadTagRepository();
            await LoadWebServiceGate();
            LoadPersistanceGate();
            await LoadWcfExportGate();
            await LoadAndWireAllKpiGates();
            await StartAndWireWebServiceGate();
        }

        private async Task LoadTagRepository()
        {
            var tags = await _dataService.GetAllTagsAsync();
            await _tagRepositoryLoader.LoadAsync(tags);
        }

        public void Dispose()
        {
            foreach (var subscription in _subscriptions)
            {
                subscription.Dispose();
            }
        }
    }
}
